/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.hibernate.mapping;

import com.ceiec.util.MyClassTools;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.tool.hbm2ddl.ColumnMetadata;
import org.hibernate.tool.hbm2ddl.TableMetadata;

import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A relational table
 *
 * @author Gavin King
 */
public class Table implements RelationalModel, Serializable {

    private String name;
    private String schema;
    private String catalog;
    /**
     * contains all columns, including the primary key
     */
    private Map columns = new LinkedHashMap();
    private KeyValue idValue;
    private PrimaryKey primaryKey;
    private Map<String, Index> indexes = new LinkedHashMap<String, Index>();
    private Map foreignKeys = new LinkedHashMap();
    private Map<String,UniqueKey> uniqueKeys = new LinkedHashMap<String,UniqueKey>();
    private int uniqueInteger;
    private boolean quoted;
    private boolean schemaQuoted;
    private boolean catalogQuoted;
    private List checkConstraints = new ArrayList();
    private String rowId;
    private String subselect;
    private boolean isAbstract;
    private boolean hasDenormalizedTables;
    private String comment;

    static class ForeignKeyKey implements Serializable {
        String referencedClassName;
        List columns;
        List referencedColumns;

        ForeignKeyKey(List columns, String referencedClassName, List referencedColumns) {
            this.referencedClassName = referencedClassName;
            this.columns = new ArrayList();
            this.columns.addAll( columns );
            if ( referencedColumns != null ) {
                this.referencedColumns = new ArrayList();
                this.referencedColumns.addAll( referencedColumns );
            }
            else {
                this.referencedColumns = Collections.EMPTY_LIST;
            }
        }

        public int hashCode() {
            return columns.hashCode() + referencedColumns.hashCode();
        }

        public boolean equals(Object other) {
            ForeignKeyKey fkk = (ForeignKeyKey) other;
            return fkk.columns.equals( columns ) &&
                    fkk.referencedClassName.equals( referencedClassName ) && fkk.referencedColumns
                    .equals( referencedColumns );
        }
    }

    public Table() { }

    public Table(String name) {
        this();
        setName( name );
    }

    public String getQualifiedName(Dialect dialect, String defaultCatalog, String defaultSchema) {
        if ( subselect != null ) {
            return "( " + subselect + " )";
        }
        String quotedName = getQuotedName( dialect );
        String usedSchema = schema == null ?
                defaultSchema :
                getQuotedSchema( dialect );
        String usedCatalog = catalog == null ?
                defaultCatalog :
                getQuotedCatalog( dialect );
//        return qualify( usedCatalog, usedSchema, quotedName );
        return qualify( usedCatalog, null, quotedName );
    }

    public static String qualify(String catalog, String schema, String table) {
        StringBuilder qualifiedName = new StringBuilder();
        if ( catalog != null ) {
            qualifiedName.append( catalog ).append( '.' );
        }
        if ( schema != null ) {
            qualifiedName.append( schema ).append( '.' );
        }
        return qualifiedName.append( table ).toString();
    }

    public String getName() {
        return name;
    }

    /**
     * returns quoted name as it would be in the mapping file.
     */
    public String getQuotedName() {
        return quoted ?
                "`" + name + "`" :
                name;
    }

    public String getQuotedName(Dialect dialect) {
        return quoted ?
                dialect.openQuote() + name + dialect.closeQuote() :
                name;
    }

    /**
     * returns quoted name as it is in the mapping file.
     */
    public String getQuotedSchema() {
        return schemaQuoted ?
                "`" + schema + "`" :
                schema;
    }

    public String getQuotedSchema(Dialect dialect) {
        return schemaQuoted ?
                dialect.openQuote() + schema + dialect.closeQuote() :
                schema;
    }

    public String getQuotedCatalog() {
        return catalogQuoted ?
                "`" + catalog + "`" :
                catalog;
    }

    public String getQuotedCatalog(Dialect dialect) {
        return catalogQuoted ?
                dialect.openQuote() + catalog + dialect.closeQuote() :
                catalog;
    }

    public void setName(String name) {
        if ( name.charAt( 0 ) == '`' ) {
            quoted = true;
            this.name = name.substring( 1, name.length() - 1 );
        }
        else {
            this.name = name;
        }
    }

    /**
     * Return the column which is identified by column provided as argument.
     *
     * @param column column with atleast a name.
     * @return the underlying column or null if not inside this table. Note: the instance *can* be different than the input parameter, but the name will be the same.
     */
    public Column getColumn(Column column) {
        if ( column == null ) {
            return null;
        }

        Column myColumn = (Column) columns.get( column.getCanonicalName() );

        return column.equals( myColumn ) ?
                myColumn :
                null;
    }

    public Column getColumn(int n) {
        Iterator iter = columns.values().iterator();
        for ( int i = 0; i < n - 1; i++ ) {
            iter.next();
        }
        return (Column) iter.next();
    }

    public void addColumn(Column column) {
        Column old = getColumn( column );
        if ( old == null ) {
            columns.put( column.getCanonicalName(), column );
            column.uniqueInteger = columns.size();
        }
        else {
            column.uniqueInteger = old.uniqueInteger;
        }
    }

    public int getColumnSpan() {
        return columns.size();
    }

    public Iterator getColumnIterator() {
        return columns.values().iterator();
    }

    public Iterator<Index> getIndexIterator() {
        return indexes.values().iterator();
    }

    public Iterator getForeignKeyIterator() {
        return foreignKeys.values().iterator();
    }

    public Iterator<UniqueKey> getUniqueKeyIterator() {
        return getUniqueKeys().values().iterator();
    }

    Map<String, UniqueKey> getUniqueKeys() {
        cleanseUniqueKeyMapIfNeeded();
        return uniqueKeys;
    }

    private int sizeOfUniqueKeyMapOnLastCleanse;

    private void cleanseUniqueKeyMapIfNeeded() {
        if ( uniqueKeys.size() == sizeOfUniqueKeyMapOnLastCleanse ) {
            // nothing to do
            return;
        }
        cleanseUniqueKeyMap();
        sizeOfUniqueKeyMapOnLastCleanse = uniqueKeys.size();
    }

    private void cleanseUniqueKeyMap() {
        // We need to account for a few conditions here...
        // 	1) If there are multiple unique keys contained in the uniqueKeys Map, we need to deduplicate
        // 		any sharing the same columns as other defined unique keys; this is needed for the annotation
        // 		processor since it creates unique constraints automagically for the user
        //	2) Remove any unique keys that share the same columns as the primary key; again, this is
        //		needed for the annotation processor to handle @Id @OneToOne cases.  In such cases the
        //		unique key is unnecessary because a primary key is already unique by definition.  We handle
        //		this case specifically because some databases fail if you try to apply a unique key to
        //		the primary key columns which causes schema export to fail in these cases.
        if ( uniqueKeys.isEmpty() ) {
            // nothing to do
            return;
        }
        else if ( uniqueKeys.size() == 1 ) {
            // we have to worry about condition 2 above, but not condition 1
            final Map.Entry<String,UniqueKey> uniqueKeyEntry = uniqueKeys.entrySet().iterator().next();
            if ( isSameAsPrimaryKeyColumns( uniqueKeyEntry.getValue() ) ) {
                uniqueKeys.remove( uniqueKeyEntry.getKey() );
            }
        }
        else {
            // we have to check both conditions 1 and 2
            final Iterator<Map.Entry<String,UniqueKey>> uniqueKeyEntries = uniqueKeys.entrySet().iterator();
            while ( uniqueKeyEntries.hasNext() ) {
                final Map.Entry<String,UniqueKey> uniqueKeyEntry = uniqueKeyEntries.next();
                final UniqueKey uniqueKey = uniqueKeyEntry.getValue();
                boolean removeIt = false;

                // condition 1 : check against other unique keys
                for ( UniqueKey otherUniqueKey : uniqueKeys.values() ) {
                    // make sure its not the same unique key
                    if ( uniqueKeyEntry.getValue() == otherUniqueKey ) {
                        continue;
                    }
                    if ( otherUniqueKey.getColumns().containsAll( uniqueKey.getColumns() )
                            && uniqueKey.getColumns().containsAll( otherUniqueKey.getColumns() ) ) {
                        removeIt = true;
                        break;
                    }
                }

                // condition 2 : check against pk
                if ( isSameAsPrimaryKeyColumns( uniqueKeyEntry.getValue() ) ) {
                    removeIt = true;
                }

                if ( removeIt ) {
                    //uniqueKeys.remove( uniqueKeyEntry.getKey() );
                    uniqueKeyEntries.remove();
                }
            }

        }
    }

    private boolean isSameAsPrimaryKeyColumns(UniqueKey uniqueKey) {
        if ( primaryKey == null || ! primaryKey.columnIterator().hasNext() ) {
            // happens for many-to-many tables
            return false;
        }
        return primaryKey.getColumns().containsAll( uniqueKey.getColumns() )
                && uniqueKey.getColumns().containsAll( primaryKey.getColumns() );
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((catalog == null) ? 0 : isCatalogQuoted() ? catalog.hashCode() : catalog.toLowerCase().hashCode());
        result = prime * result + ((name == null) ? 0 : isQuoted() ? name.hashCode() : name.toLowerCase().hashCode());
        result = prime * result
                + ((schema == null) ? 0 : isSchemaQuoted() ? schema.hashCode() : schema.toLowerCase().hashCode());
        return result;
    }

    @Override
    public boolean equals(Object object) {
        return object instanceof Table && equals((Table) object);
    }

    public boolean equals(Table table) {
        if (null == table) {
            return false;
        }
        if (this == table) {
            return true;
        }

        return isQuoted() ? name.equals(table.getName()) : name.equalsIgnoreCase(table.getName())
                && ((schema == null && table.getSchema() != null) ? false : (schema == null) ? true : isSchemaQuoted() ? schema.equals(table.getSchema()) : schema.equalsIgnoreCase(table.getSchema()))
                && ((catalog == null && table.getCatalog() != null) ? false : (catalog == null) ? true : isCatalogQuoted() ? catalog.equals(table.getCatalog()) : catalog.equalsIgnoreCase(table.getCatalog()));
    }

    public void validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo) {
        Iterator iter = getColumnIterator();
        while ( iter.hasNext() ) {
            Column col = (Column) iter.next();

            ColumnMetadata columnInfo = tableInfo.getColumnMetadata( col.getName() );

            if ( columnInfo == null ) {
                throw new HibernateException( "Missing column: " + col.getName() + " in " + Table.qualify( tableInfo.getCatalog(), tableInfo.getSchema(), tableInfo.getName()));
            }
            else {
                final boolean typesMatch = col.getSqlType( dialect, mapping ).toLowerCase()
                        .startsWith( columnInfo.getTypeName().toLowerCase() )
                        || columnInfo.getTypeCode() == col.getSqlTypeCode( mapping );
                if ( !typesMatch ) {
                    throw new HibernateException(
                            "Wrong column type in " +
                                    Table.qualify( tableInfo.getCatalog(), tableInfo.getSchema(), tableInfo.getName()) +
                                    " for column " + col.getName() +
                                    ". Found: " + columnInfo.getTypeName().toLowerCase() +
                                    ", expected: " + col.getSqlType( dialect, mapping )
                    );
                }
            }
        }

    }

    public Iterator sqlAlterStrings(Dialect dialect, Mapping p, TableMetadata tableInfo, String defaultCatalog,
                                    String defaultSchema)
            throws HibernateException {

        StringBuilder root = new StringBuilder( "alter table " )
                .append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
                .append( ' ' )
                .append( dialect.getAddColumnString() );

        Iterator iter = getColumnIterator();
        List results = new ArrayList();

        while ( iter.hasNext() ) {
            Column column = (Column) iter.next();

            ColumnMetadata columnInfo = tableInfo.getColumnMetadata( column.getName() );

            if ( columnInfo == null ) {
                // the column doesnt exist at all.
                StringBuilder alter = new StringBuilder( root.toString() )
                        .append( ' ' )
                        .append( column.getQuotedName( dialect ) )
                        .append( ' ' )
                        .append( column.getSqlType( dialect, p ) );

                String defaultValue = column.getDefaultValue();
                if ( defaultValue != null ) {
                    alter.append( " default " ).append( defaultValue );
                }

                if ( column.isNullable() ) {
                    alter.append( dialect.getNullColumnString() );
                }
                else {
                    alter.append( " not null" );
                }

                if ( column.isUnique() ) {
                    String keyName = Constraint.generateName( "UK_", this, column );
                    UniqueKey uk = getOrCreateUniqueKey( keyName );
                    uk.addColumn( column );
                    alter.append( dialect.getUniqueDelegate()
                            .getColumnDefinitionUniquenessFragment( column ) );
                }

                if ( column.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
                    alter.append( " check(" )
                            .append( column.getCheckConstraint() )
                            .append( ")" );
                }

                String columnComment = column.getComment();
                if ( columnComment != null ) {
                    alter.append( dialect.getColumnComment( columnComment ) );
                }

                alter.append( dialect.getAddColumnSuffixString() );

                results.add( alter.toString() );
            }

        }

        return results.iterator();
    }

    public boolean hasPrimaryKey() {
        return getPrimaryKey() != null;
    }

    public String sqlTemporaryTableCreateString(Dialect dialect, Mapping mapping) throws HibernateException {
        StringBuilder buffer = new StringBuilder( dialect.getCreateTemporaryTableString() )
                .append( ' ' )
                .append( name )
                .append( " (" );
        Iterator itr = getColumnIterator();
        while ( itr.hasNext() ) {
            final Column column = (Column) itr.next();
            buffer.append( column.getQuotedName( dialect ) ).append( ' ' );
            buffer.append( column.getSqlType( dialect, mapping ) );
            if ( column.isNullable() ) {
                buffer.append( dialect.getNullColumnString() );
            }
            else {
                buffer.append( " not null" );
            }
            if ( itr.hasNext() ) {
                buffer.append( ", " );
            }
        }
        buffer.append( ") " );
        buffer.append( dialect.getCreateTemporaryTablePostfix() );
        return buffer.toString();
    }

    public String sqlCreateStringCustomed(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema,HashMap<String,String> fieldCommentMap) {
        /**
         * 构造大写table名--》驼峰化的class 类名转换map
         */
        Set<Class<?>> classes = MyClassTools.getClasses("com.ceiec.model");
        HashMap<String, String> map = new HashMap<>();
        for (Class<?> aClass : classes) {
            javax.persistence.Table  annotation = aClass.getAnnotation(javax.persistence.Table .class);
            if (annotation == null) {
                System.out.println(aClass.getName() + " is bad");
                continue;
            }
            String name = annotation.name();
            map.put(name,aClass.getSimpleName());
        }
        String originName = getQualifiedName(dialect, defaultCatalog, defaultSchema);
        String lowerCaseTableName = map.get(originName);
        if (lowerCaseTableName == null) {
            lowerCaseTableName = originName;
        } else {
            lowerCaseTableName = processStr(lowerCaseTableName);
        }



        StringBuilder buf = new StringBuilder( hasPrimaryKey() ? dialect.getCreateTableString() : dialect.getCreateMultisetTableString() )
                .append( ' ' )
                .append(  lowerCaseTableName )
                .append( " (" );

        boolean identityColumn = idValue != null && idValue.isIdentityColumn( p.getIdentifierGeneratorFactory(), dialect );

        // Try to find out the name of the primary key to create it as identity if the IdentityGenerator is used
        String pkname = null;
        if ( hasPrimaryKey() && identityColumn ) {
            pkname = ( (Column) getPrimaryKey().getColumnIterator().next() ).getQuotedName( dialect );
        }

        Iterator iter = getColumnIterator();
        while ( iter.hasNext() ) {
            Column col = (Column) iter.next();

            String originCamelCaseColName = col.getQuotedName(dialect);
            String quotedName = originCamelCaseColName;
            //转成带下划线的
            quotedName = processStr(quotedName);
            buf.append(quotedName)
                    .append( ' ' );

            if ( identityColumn && quotedName.equals( pkname ) ) {
                // to support dialects that have their own identity data type
                if ( dialect.hasDataTypeInIdentityColumn() ) {
                    buf.append( col.getSqlType( dialect, p ) );
                }
                buf.append( ' ' )
                        .append( dialect.getIdentityColumnString( col.getSqlTypeCode( p ) ) );
            }
            else {

                buf.append( col.getSqlType( dialect, p ) );

                String defaultValue = col.getDefaultValue();
                if ( defaultValue != null ) {
                    buf.append( " default " ).append( defaultValue );
                }

                if ( col.isNullable() ) {
                    buf.append( dialect.getNullColumnString() );
                }
                else {
                    buf.append( " not null" );
                }

            }

            if ( col.isUnique() ) {
                String keyName = Constraint.generateName( "UK_", this, col );
                UniqueKey uk = getOrCreateUniqueKey( keyName );
                uk.addColumn( col );
                buf.append( dialect.getUniqueDelegate()
                        .getColumnDefinitionUniquenessFragment( col ) );
            }

            if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
                buf.append( " check (" )
                        .append( col.getCheckConstraint() )
                        .append( ")" );
            }
            if (fieldCommentMap != null) {
                if (originCamelCaseColName == null) {
                    throw new RuntimeException(lowerCaseTableName + " error ");
                }

                String s = fieldCommentMap.get(originCamelCaseColName.toLowerCase());
                if (s != null) {
                    buf.append(" COMMENT '").append(s).append("'");
                }
            }
//            String columnComment = col.getComment();
//            if ( columnComment != null ) {
//                buf.append( dialect.getColumnComment( columnComment ) );
//            }


            if ( iter.hasNext() ) {
                buf.append( ", " );
            }

        }
        if ( hasPrimaryKey() ) {
            buf.append( ", " )
                    .append( getPrimaryKey().sqlConstraintString( dialect ) );
        }

        buf.append( dialect.getUniqueDelegate().getTableCreationUniqueConstraintsFragment( this ) );

        if ( dialect.supportsTableCheck() ) {
            Iterator chiter = checkConstraints.iterator();
            while ( chiter.hasNext() ) {
                buf.append( ", check (" )
                        .append( chiter.next() )
                        .append( ')' );
            }
        }

        buf.append( ')' );

        if ( comment != null ) {
            buf.append( dialect.getTableComment( comment ) );
        }

        return buf.append( dialect.getTableTypeString() ).toString();
    }

    public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
        /**
         * 构造大写table名--》驼峰化的class 类名转换map
         */
        Set<Class<?>> classes = MyClassTools.getClasses("com.ceiec.scm.model");
        HashMap<String, String> map = new HashMap<>();
        for (Class<?> aClass : classes) {
            javax.persistence.Table  annotation = aClass.getAnnotation(javax.persistence.Table .class);
            if (annotation == null) {
                System.out.println(aClass.getName() + " is bad");
                continue;
            }
            String name = annotation.name();
            map.put(name,aClass.getSimpleName());
        }
        String originName = getQualifiedName(dialect, defaultCatalog, defaultSchema);
        String lowerCaseTableName = map.get(originName);
        if (lowerCaseTableName == null) {
            lowerCaseTableName = originName;
        } else {
            lowerCaseTableName = processStr(lowerCaseTableName);
        }



        StringBuilder buf = new StringBuilder( hasPrimaryKey() ? dialect.getCreateTableString() : dialect.getCreateMultisetTableString() )
                .append( ' ' )
                .append(  lowerCaseTableName )
                .append( " (" );

        boolean identityColumn = idValue != null && idValue.isIdentityColumn( p.getIdentifierGeneratorFactory(), dialect );

        // Try to find out the name of the primary key to create it as identity if the IdentityGenerator is used
        String pkname = null;
        if ( hasPrimaryKey() && identityColumn ) {
            pkname = ( (Column) getPrimaryKey().getColumnIterator().next() ).getQuotedName( dialect );
        }

        Iterator iter = getColumnIterator();
        while ( iter.hasNext() ) {
            Column col = (Column) iter.next();

            String quotedName = col.getQuotedName(dialect);
            //转成带下划线的
            quotedName = processStr(quotedName);
            buf.append(quotedName)
                    .append( ' ' );

            if ( identityColumn && quotedName.equals( pkname ) ) {
                // to support dialects that have their own identity data type
                if ( dialect.hasDataTypeInIdentityColumn() ) {
                    buf.append( col.getSqlType( dialect, p ) );
                }
                buf.append( ' ' )
                        .append( dialect.getIdentityColumnString( col.getSqlTypeCode( p ) ) );
            }
            else {

                buf.append( col.getSqlType( dialect, p ) );

                String defaultValue = col.getDefaultValue();
                if ( defaultValue != null ) {
                    buf.append( " default " ).append( defaultValue );
                }

                if ( col.isNullable() ) {
                    buf.append( dialect.getNullColumnString() );
                }
                else {
                    buf.append( " not null" );
                }

            }

            if ( col.isUnique() ) {
                String keyName = Constraint.generateName( "UK_", this, col );
                UniqueKey uk = getOrCreateUniqueKey( keyName );
                uk.addColumn( col );
                buf.append( dialect.getUniqueDelegate()
                        .getColumnDefinitionUniquenessFragment( col ) );
            }

            if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
                buf.append( " check (" )
                        .append( col.getCheckConstraint() )
                        .append( ")" );
            }


//            String columnComment = col.getComment();
//            if ( columnComment != null ) {
//                buf.append( dialect.getColumnComment( columnComment ) );
//            }


            if ( iter.hasNext() ) {
                buf.append( ", " );
            }

        }
        if ( hasPrimaryKey() ) {
            buf.append( ", " )
                    .append( getPrimaryKey().sqlConstraintString( dialect ) );
        }

        buf.append( dialect.getUniqueDelegate().getTableCreationUniqueConstraintsFragment( this ) );

        if ( dialect.supportsTableCheck() ) {
            Iterator chiter = checkConstraints.iterator();
            while ( chiter.hasNext() ) {
                buf.append( ", check (" )
                        .append( chiter.next() )
                        .append( ')' );
            }
        }

        buf.append( ')' );

        if ( comment != null ) {
            buf.append( dialect.getTableComment( comment ) );
        }

        return buf.append( dialect.getTableTypeString() ).toString();
    }

    private static String processStr(String para) {
        System.out.println("process " + para);
        StringBuilder sb=new StringBuilder(para);
        int temp=0;//定位
        if (!para.contains("_")) {
            for(int i=0;i<para.length();i++){
                if(Character.isUpperCase(para.charAt(i))){
                    sb.insert(i+temp, "_");
                    temp+=1;
                }
            }
        }
        String s = sb.toString().toLowerCase();
        if (s.startsWith("_")) {
            s = s.substring(1);
        }
        return s;
    }

    public static void main(String[] args) throws IOException {
        Set<Class<?>> classes = MyClassTools.getClasses("com.ceiec.model");
        HashMap<String, String> map = new HashMap<>();
        for (Class<?> aClass : classes) {
            javax.persistence.Table  annotation = aClass.getAnnotation(javax.persistence.Table .class);
            if (annotation == null) {
                System.out.println(aClass.getName() + " is bad");
                continue;
            }
            String name = annotation.name();
            map.put(name,aClass.getSimpleName());
        }

        Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources("com.ceiec.model");
        while (resources.hasMoreElements()){
            URL url = resources.nextElement();
        }
        String abcDkask = processStr("resourceDispatchNum");
        System.out.println(abcDkask);
    }

    public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
        return dialect.getDropTableString( getQualifiedName( dialect, defaultCatalog, defaultSchema ) );
    }

    public PrimaryKey getPrimaryKey() {
        return primaryKey;
    }

    public void setPrimaryKey(PrimaryKey primaryKey) {
        this.primaryKey = primaryKey;
    }

    public Index getOrCreateIndex(String indexName) {

        Index index =  indexes.get( indexName );

        if ( index == null ) {
            index = new Index();
            index.setName( indexName );
            index.setTable( this );
            indexes.put( indexName, index );
        }

        return index;
    }

    public Index getIndex(String indexName) {
        return  indexes.get( indexName );
    }

    public Index addIndex(Index index) {
        Index current =  indexes.get( index.getName() );
        if ( current != null ) {
            throw new MappingException( "Index " + index.getName() + " already exists!" );
        }
        indexes.put( index.getName(), index );
        return index;
    }

    public UniqueKey addUniqueKey(UniqueKey uniqueKey) {
        UniqueKey current = uniqueKeys.get( uniqueKey.getName() );
        if ( current != null ) {
            throw new MappingException( "UniqueKey " + uniqueKey.getName() + " already exists!" );
        }
        uniqueKeys.put( uniqueKey.getName(), uniqueKey );
        return uniqueKey;
    }

    public UniqueKey createUniqueKey(List keyColumns) {
        String keyName = Constraint.generateName( "UK_", this, keyColumns );
        UniqueKey uk = getOrCreateUniqueKey( keyName );
        uk.addColumns( keyColumns.iterator() );
        return uk;
    }

    public UniqueKey getUniqueKey(String keyName) {
        return uniqueKeys.get( keyName );
    }

    public UniqueKey getOrCreateUniqueKey(String keyName) {
        UniqueKey uk = uniqueKeys.get( keyName );

        if ( uk == null ) {
            uk = new UniqueKey();
            uk.setName( keyName );
            uk.setTable( this );
            uniqueKeys.put( keyName, uk );
        }
        return uk;
    }

    public void createForeignKeys() {
    }

    public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName) {
        return createForeignKey( keyName, keyColumns, referencedEntityName, null );
    }

    public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName,
                                       List referencedColumns) {
        Object key = new ForeignKeyKey( keyColumns, referencedEntityName, referencedColumns );

        ForeignKey fk = (ForeignKey) foreignKeys.get( key );
        if ( fk == null ) {
            fk = new ForeignKey();
            fk.setTable( this );
            fk.setReferencedEntityName( referencedEntityName );
            fk.addColumns( keyColumns.iterator() );
            if ( referencedColumns != null ) {
                fk.addReferencedColumns( referencedColumns.iterator() );
            }

            if ( keyName != null ) {
                fk.setName( keyName );
            }
            else {
                fk.setName( Constraint.generateName( fk.generatedConstraintNamePrefix(),
                        this, keyColumns ) );
            }

            foreignKeys.put( key, fk );
        }

        if ( keyName != null ) {
            fk.setName( keyName );
        }

        return fk;
    }



    public String getSchema() {
        return schema;
    }

    public void setSchema(String schema) {
        if ( schema != null && schema.charAt( 0 ) == '`' ) {
            schemaQuoted = true;
            this.schema = schema.substring( 1, schema.length() - 1 );
        }
        else {
            this.schema = schema;
        }
    }

    public String getCatalog() {
        return catalog;
    }

    public void setCatalog(String catalog) {
        if ( catalog != null && catalog.charAt( 0 ) == '`' ) {
            catalogQuoted = true;
            this.catalog = catalog.substring( 1, catalog.length() - 1 );
        }
        else {
            this.catalog = catalog;
        }
    }

    // This must be done outside of Table, rather than statically, to ensure
    // deterministic alias names.  See HHH-2448.
    public void setUniqueInteger( int uniqueInteger ) {
        this.uniqueInteger = uniqueInteger;
    }

    public int getUniqueInteger() {
        return uniqueInteger;
    }

    public void setIdentifierValue(KeyValue idValue) {
        this.idValue = idValue;
    }

    public KeyValue getIdentifierValue() {
        return idValue;
    }

    public boolean isSchemaQuoted() {
        return schemaQuoted;
    }
    public boolean isCatalogQuoted() {
        return catalogQuoted;
    }

    public boolean isQuoted() {
        return quoted;
    }

    public void setQuoted(boolean quoted) {
        this.quoted = quoted;
    }

    public void addCheckConstraint(String constraint) {
        checkConstraints.add( constraint );
    }

    public boolean containsColumn(Column column) {
        return columns.containsValue( column );
    }

    public String getRowId() {
        return rowId;
    }

    public void setRowId(String rowId) {
        this.rowId = rowId;
    }

    public String toString() {
        StringBuilder buf = new StringBuilder().append( getClass().getName() )
                .append( '(' );
        if ( getCatalog() != null ) {
            buf.append( getCatalog() + "." );
        }
        if ( getSchema() != null ) {
            buf.append( getSchema() + "." );
        }
        buf.append( getName() ).append( ')' );
        return buf.toString();
    }

    public String getSubselect() {
        return subselect;
    }

    public void setSubselect(String subselect) {
        this.subselect = subselect;
    }

    public boolean isSubselect() {
        return subselect != null;
    }

    public boolean isAbstractUnionTable() {
        return hasDenormalizedTables() && isAbstract;
    }

    public boolean hasDenormalizedTables() {
        return hasDenormalizedTables;
    }

    void setHasDenormalizedTables() {
        hasDenormalizedTables = true;
    }

    public void setAbstract(boolean isAbstract) {
        this.isAbstract = isAbstract;
    }

    public boolean isAbstract() {
        return isAbstract;
    }

    public boolean isPhysicalTable() {
        return !isSubselect() && !isAbstractUnionTable();
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public Iterator getCheckConstraintsIterator() {
        return checkConstraints.iterator();
    }

    public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) {
        List comments = new ArrayList();
        if ( dialect.supportsCommentOn() ) {
            String tableName = getQualifiedName( dialect, defaultCatalog, defaultSchema );
            if ( comment != null ) {
                StringBuilder buf = new StringBuilder()
                        .append( "comment on table " )
                        .append( tableName )
                        .append( " is '" )
                        .append( comment )
                        .append( "'" );
                comments.add( buf.toString() );
            }
            Iterator iter = getColumnIterator();
            while ( iter.hasNext() ) {
                Column column = (Column) iter.next();
                String columnComment = column.getComment();
                if ( columnComment != null ) {
                    StringBuilder buf = new StringBuilder()
                            .append( "comment on column " )
                            .append( tableName )
                            .append( '.' )
                            .append( column.getQuotedName( dialect ) )
                            .append( " is '" )
                            .append( columnComment )
                            .append( "'" );
                    comments.add( buf.toString() );
                }
            }
        }
        return comments.iterator();
    }

}
